#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "bsp.h"

/************************************************
设置系统时间
参数:*dt数据格式为"2006-4-20 20:30:30"
调用方法:
char *pt="2006-4-20 20:30:30";
**************************************************/
int hal_set_time(char *pTime)
{
    char cmdbuf[128] = {0};
    sprintf(cmdbuf, "date -s \"%s\"", pTime);
    system(cmdbuf);
    system("hwclock -w -f /dev/rtc0");//LC320有自己的硬件时钟需要设置
    return 0;
}

#define ZOOMSIZE    12
#define XXSIZE      3
videoeptz_t zoomup[ZOOMSIZE + 1];
videoeptz_t zoomdown[ZOOMSIZE + 1];
/***********
 * hal_crop_zoom 无极放大
 * offsetx：相对于屏幕中心的x偏移量
 * offsety：相对于屏幕中心的y偏移量
 * xx：放大倍率 0-30 对应 1-4倍
 * ZOOMSIZE 无极放大数组大小 不宜过大
 * XXSIZE 传入放大值范围
 * 需修改 w_original osd_w 
 * 可修改 ：ZOOMSIZE XXSIZE 
 * 枪瞄建议 ZOOMSIZE = 120 XXSIZE = 30 xx 0-30
 * 手持建议 ZOOMSIZE = 12 XXSIZE = 3 xx 0-3
***********/
int hal_crop_zoom(int offsetx, int offsety, float wflag, float hflag, unsigned int xx)
{
    static int initzoom, zoomdir;
    static int lastx, lasty, lastxx = 0;    // 之前偏移量
    static int zoomcnts, zoomindex; // 输出zoom索引
    // static float wflag = 0.5;	// 机芯到wifi板的放大倍率

    if (offsetx != lastx || offsety != lasty || initzoom == 0) {
        for (int xxtemp = 0; xxtemp <= ZOOMSIZE; xxtemp++) {
            float amplify = 1.0 + (float)(xxtemp * 3.0 / ZOOMSIZE); // 1.0 -> 4.0
            amplify = amplify * amplify;
            zoomup[xxtemp].fzoom = (float)(1.0 / amplify);
            zoomup[xxtemp].offsetx = offsetx * wflag * (1 - sqrt(amplify));
            zoomup[xxtemp].offsety = offsety * hflag * (1 - sqrt(amplify));
            zoomup[xxtemp].flag = xxtemp + 1;
        }
        for (int xxtemp = 0; xxtemp <= ZOOMSIZE; xxtemp++) {
            zoomdown[xxtemp].fzoom = zoomup[ZOOMSIZE - xxtemp].fzoom;
            zoomdown[xxtemp].offsetx = zoomup[ZOOMSIZE - xxtemp].offsetx;
            zoomdown[xxtemp].offsety = zoomup[ZOOMSIZE - xxtemp].offsety;
            zoomdown[xxtemp].flag = xxtemp + 1;
        }
        initzoom = 1;
        lastx = offsetx;
        lasty = offsety;
    }
    zoomcnts = (xx - lastxx) * (ZOOMSIZE / XXSIZE); // zoomcnts 一次的数量不宜过大 (<=20)
    zoomindex = lastxx * (ZOOMSIZE / XXSIZE) + zoomcnts;
    if (zoomcnts > 0) {
        eptz_msg_send2(&zoomup[zoomindex - zoomcnts], zoomcnts + 1);
        lastxx = xx;
        zoomdir = 1;
    } else if (zoomcnts < 0) {
        eptz_msg_send2(&zoomdown[ZOOMSIZE - zoomindex + zoomcnts], -zoomcnts + 1);
        lastxx = xx;
        zoomdir = -1;
    } else if (zoomcnts == 0) {
        if (zoomdir > 0) {
            eptz_msg_send2(&zoomup[zoomindex], 1);
        } else if (zoomdir < 0) {
            eptz_msg_send2(&zoomdown[ZOOMSIZE - zoomindex + zoomcnts], 1);
        }
        lastxx = xx;
    }
    return 0;
}

struct yuv_color {
    int y;
    int u;
    int v;
};

struct yuv_color color[] = {
    {255, 128, 128},    // white
    {0, 128, 128},      // black
    {0, 0, 255},        // red
    {0, 0, 0},          // green
};

#define SIZE_R_Y_720X480   1501
#define SIZE_R_UV_720X480  613
extern short int R_Y_720X480[];
extern short int R_UV_720X480[];
#define SIZE_R_Y_1024X768   3065
#define SIZE_R_UV_1024X768  1175
extern short int R_Y_1024X768[];
extern short int R_UV_1024X768[];
#define SIZE_R_Y_1280X720   2343
#define SIZE_R_UV_1280X720  962
extern short int R_Y_1280X720[];
extern short int R_UV_1280X720[];
#define SIZE_R_Y_1280X1024   3065
#define SIZE_R_UV_1280X1024  1175
extern short int R_Y_1280X1024[];
extern short int R_UV_1280X1024[];
#define SIZE_R_Y_1920X1080   3909
#define SIZE_R_UV_1920X1080  1525
extern short int R_Y_1920X1080[];
extern short int R_UV_1920X1080[];

int hal_cross_update(int onoff, int cross_type, int cross_color, int offsetx, int offsety)
{
    if (onoff) {
        unsigned char *pcrossY = NULL, *pcrossU = NULL, *pcrossV = NULL;
        unsigned int outsizeY = 0, outsizeU = 0, outsizeV = 0;

        int r_y_720x480[SIZE_R_Y_720X480 * 3], r_u_720x480[SIZE_R_UV_720X480 * 3], r_v_720x480[SIZE_R_UV_720X480 * 3];
        int r_y_1024x768[SIZE_R_Y_1024X768 * 3], r_u_1024x768[SIZE_R_UV_1024X768 * 3], r_v_1024x768[SIZE_R_UV_1024X768 * 3];
        int r_y_1280x720[SIZE_R_Y_1280X720 * 3], r_u_1280x720[SIZE_R_UV_1280X720 * 3], r_v_1280x720[SIZE_R_UV_1280X720 * 3];
        int r_y_1280x1024[SIZE_R_Y_1280X1024 * 3], r_u_1280x1024[SIZE_R_UV_1280X1024 * 3], r_v_1280x1024[SIZE_R_UV_1280X1024 * 3];
        int r_y_1920x1080[SIZE_R_Y_1920X1080 * 3], r_u_1920x1080[SIZE_R_UV_1920X1080 * 3], r_v_1920x1080[SIZE_R_UV_1920X1080 * 3];
        int i = 0;

        switch (cross_type)
        {
        case 0:
            for(i = 0; i < SIZE_R_Y_720X480; i++) {
                r_y_720x480[3 * i] = R_Y_720X480[2 * i];
                r_y_720x480[3 * i + 1] = R_Y_720X480[2 * i + 1];
                r_y_720x480[3 * i + 2] = color[cross_color].y;
            }

            for(i = 0; i < SIZE_R_UV_720X480; i++) {
                r_u_720x480[3 * i] = R_UV_720X480[2 *i];
                r_u_720x480[3 * i + 1] = R_UV_720X480[2 * i + 1];
                r_u_720x480[3 * i + 2] = color[cross_color].u;

                r_v_720x480[3 * i] = R_UV_720X480[2 * i];
                r_v_720x480[3 * i + 1] = R_UV_720X480[2 * i + 1];
                r_v_720x480[3 * i + 2] = color[cross_color].v;

                if(offsetx < 0 && abs(offsetx) % 2 != 0) {
                    r_u_720x480[3 * i]--;
                    r_v_720x480[3 * i]--;
                }

                if(offsety > 0 && abs(offsety) % 2 != 0) {
                    r_u_720x480[3 * i + 1]++;
                    r_v_720x480[3 * i + 1]++;
                }
            }
            pcrossY = (unsigned char *)r_y_720x480;
            pcrossU = (unsigned char *)r_u_720x480;
            pcrossV = (unsigned char *)r_v_720x480;
            outsizeY = sizeof(r_y_720x480) / sizeof(char);
            outsizeU = sizeof(r_u_720x480) / sizeof(char);
            outsizeV = sizeof(r_v_720x480) / sizeof(char);
            break;
        case 1:
            for(i = 0; i < SIZE_R_Y_1024X768; i++) {
                r_y_1024x768[3 * i] = R_Y_1024X768[2 * i];
                r_y_1024x768[3 * i + 1] = R_Y_1024X768[2 * i + 1];
                r_y_1024x768[3 * i + 2] = color[cross_color].y;
            }

            for(i = 0; i < SIZE_R_UV_1024X768; i++) {
                r_u_1024x768[3 * i] = R_UV_1024X768[2 *i];
                r_u_1024x768[3 * i + 1] = R_UV_1024X768[2 * i + 1];
                r_u_1024x768[3 * i + 2] = color[cross_color].u;

                r_v_1024x768[3 * i] = R_UV_1024X768[2 * i];
                r_v_1024x768[3 * i + 1] = R_UV_1024X768[2 * i + 1];
                r_v_1024x768[3 * i + 2] = color[cross_color].v;

                if(offsetx < 0 && abs(offsetx) % 2 != 0) {
                    r_u_1024x768[3 * i]--;
                    r_v_1024x768[3 * i]--;
                }

                if(offsety > 0 && abs(offsety) % 2 != 0) {
                    r_u_1024x768[3 * i + 1]++;
                    r_v_1024x768[3 * i + 1]++;
                }
            }
            pcrossY = (unsigned char *)r_y_1024x768;
            pcrossU = (unsigned char *)r_u_1024x768;
            pcrossV = (unsigned char *)r_v_1024x768;
            outsizeY = sizeof(r_y_1024x768) / sizeof(char);
            outsizeU = sizeof(r_u_1024x768) / sizeof(char);
            outsizeV = sizeof(r_v_1024x768) / sizeof(char);
            break;
        case 2:
            for(i = 0; i < SIZE_R_Y_1280X720; i++) {
                r_y_1280x720[3 * i] = R_Y_1280X720[2 * i];
                r_y_1280x720[3 * i + 1] = R_Y_1280X720[2 * i + 1];
                r_y_1280x720[3 * i + 2] = color[cross_color].y;
            }

            for(i = 0; i < SIZE_R_UV_1280X720; i++) {
                r_u_1280x720[3 * i] = R_UV_1280X720[2 *i];
                r_u_1280x720[3 * i + 1] = R_UV_1280X720[2 * i + 1];
                r_u_1280x720[3 * i + 2] = color[cross_color].u;

                r_v_1280x720[3 * i] = R_UV_1280X720[2 * i];
                r_v_1280x720[3 * i + 1] = R_UV_1280X720[2 * i + 1];
                r_v_1280x720[3 * i + 2] = color[cross_color].v;

                if(offsetx < 0 && abs(offsetx) % 2 != 0) {
                    r_u_1280x720[3 * i]--;
                    r_v_1280x720[3 * i]--;
                }

                if(offsety > 0 && abs(offsety) % 2 != 0) {
                    r_u_1280x720[3 * i + 1]++;
                    r_v_1280x720[3 * i + 1]++;
                }
            }
            pcrossY = (unsigned char *)r_y_1280x720;
            pcrossU = (unsigned char *)r_u_1280x720;
            pcrossV = (unsigned char *)r_v_1280x720;
            outsizeY = sizeof(r_y_1280x720) / sizeof(char);
            outsizeU = sizeof(r_u_1280x720) / sizeof(char);
            outsizeV = sizeof(r_v_1280x720) / sizeof(char);
            break;
        case 3:
            for(i = 0; i < SIZE_R_Y_1280X1024; i++) {
                r_y_1280x1024[3 * i] = R_Y_1280X1024[2 * i];
                r_y_1280x1024[3 * i + 1] = R_Y_1280X1024[2 * i + 1];
                r_y_1280x1024[3 * i + 2] = color[cross_color].y;
            }

            for(i = 0; i < SIZE_R_UV_1280X1024; i++) {
                r_u_1280x1024[3 * i] = R_UV_1280X1024[2 *i];
                r_u_1280x1024[3 * i + 1] = R_UV_1280X1024[2 * i + 1];
                r_u_1280x1024[3 * i + 2] = color[cross_color].u;

                r_v_1280x1024[3 * i] = R_UV_1280X1024[2 * i];
                r_v_1280x1024[3 * i + 1] = R_UV_1280X1024[2 * i + 1];
                r_v_1280x1024[3 * i + 2] = color[cross_color].v;

                if(offsetx < 0 && abs(offsetx) % 2 != 0) {
                    r_u_1280x1024[3 * i]--;
                    r_v_1280x1024[3 * i]--;
                }

                if(offsety > 0 && abs(offsety) % 2 != 0) {
                    r_u_1280x1024[3 * i + 1]++;
                    r_v_1280x1024[3 * i + 1]++;
                }
            }
            pcrossY = (unsigned char *)r_y_1280x1024;
            pcrossU = (unsigned char *)r_u_1280x1024;
            pcrossV = (unsigned char *)r_v_1280x1024;
            outsizeY = sizeof(r_y_1280x1024) / sizeof(char);
            outsizeU = sizeof(r_u_1280x1024) / sizeof(char);
            outsizeV = sizeof(r_v_1280x1024) / sizeof(char);
            break;
        case 4:
            for(i = 0; i < SIZE_R_Y_1920X1080; i++) {
                r_y_1920x1080[3 * i] = R_Y_1920X1080[2 * i];
                r_y_1920x1080[3 * i + 1] = R_Y_1920X1080[2 * i + 1];
                r_y_1920x1080[3 * i + 2] = color[cross_color].y;
            }

            for(i = 0; i < SIZE_R_UV_1920X1080; i++) {
                r_u_1920x1080[3 * i] = R_UV_1920X1080[2 *i];
                r_u_1920x1080[3 * i + 1] = R_UV_1920X1080[2 * i + 1];
                r_u_1920x1080[3 * i + 2] = color[cross_color].u;

                r_v_1920x1080[3 * i] = R_UV_1920X1080[2 * i];
                r_v_1920x1080[3 * i + 1] = R_UV_1920X1080[2 * i + 1];
                r_v_1920x1080[3 * i + 2] = color[cross_color].v;

                if(offsetx < 0 && abs(offsetx) % 2 != 0) {
                    r_u_1920x1080[3 * i]--;
                    r_v_1920x1080[3 * i]--;
                }

                if(offsety > 0 && abs(offsety) % 2 != 0) {
                    r_u_1920x1080[3 * i + 1]++;
                    r_v_1920x1080[3 * i + 1]++;
                }
            }
            pcrossY = (unsigned char *)r_y_1920x1080;
            pcrossU = (unsigned char *)r_u_1920x1080;
            pcrossV = (unsigned char *)r_v_1920x1080;
            outsizeY = sizeof(r_y_1920x1080) / sizeof(char);
            outsizeU = sizeof(r_u_1920x1080) / sizeof(char);
            outsizeV = sizeof(r_v_1920x1080) / sizeof(char);
            break;
        }
        
        /* Write data to the output file: first the header, then each part */
        FILE *outfile = fopen("/tmp/cross_y.bin", "wb");
        fwrite(pcrossY, 1, outsizeY, outfile);
        fclose(outfile);

        outfile = fopen("/tmp/cross_u.bin", "wb");
        fwrite(pcrossU, 1, outsizeU, outfile);
        fclose(outfile);

        outfile = fopen("/tmp/cross_v.bin", "wb");
        fwrite(pcrossV, 1, outsizeV, outfile);
        fclose(outfile);

        return cross_draw_msg_send(1, offsetx, offsety, 0, 0, 0);
    } else {
        return cross_draw_msg_send(0, offsetx, offsety, 0, 0, 0);
    }
}